package run;

/*
 * ServerFrame.java   2001-02-08
 *
 * Copyright (c) 2001 Robert Laganiere and Timothy C. Lethbridge.
 * All Rights Reserved.
 *
 */

//ff

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.sql.*;
import java.awt.*;
import java.awt.event.*;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.Scanner;

import javax.swing.JOptionPane;

import control.ConnectionManage;
import db.parking.beans.Parking;
import db.parking.beans.ParkingLot;
import db.parking.beans.rates;
import db.tables.AdminParking;
import db.tables.AdminRates;
import db.tables.ParkingLotAdmin;
import server.SimpleServer;

/**
 * The <code> ServerFrame </code> class is a simple interactive application made
 * to exercise the OCSF framework.
 * <p>
 * Type <code>java ocsftester.ServerFrame port_number</code> to start the
 * server.
 * <p>
 * The window is red when the server is closed, yellow when the server is
 * stopped and green when open.
 * 
 * @author Dr. Robert Lagani&egrave;re
 * @version February 2001
 * @see ocsftester.SimpleServer
 */
public class ServerFrame extends Frame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Button closeB = new Button("Close");
	private Button listenB = new Button("Listen");
	private Button quitB = new Button("Quit");
	private TextField port = new TextField("12345");
	private TextField backlog = new TextField("5");
	private TextField timeout = new TextField("500");

	private TextField dbUser = new TextField("root");
	private TextField dbPass = new TextField();
	private TextField dbName = new TextField();
	
	private TextField dbHost = new TextField("localhost");
	private TextField dbPort = new TextField("3306");

	private Label lblDBU = new Label("DB username:", Label.RIGHT);
	private Label lblDBP = new Label("DB pass:", Label.RIGHT);
	private Label lblDBNAME = new Label("DB name:", Label.RIGHT);
	
	private Label lblDBH = new Label("DB host:", Label.RIGHT);
	private Label lblDBPP = new Label("DB port:", Label.RIGHT);

	private Label portLB = new Label("Server Port: ", Label.RIGHT);
	private Label timeoutLB = new Label("Conn Timeout: ", Label.RIGHT);
	private Label backlogLB = new Label("Conn Backlog: ", Label.RIGHT);
	private List liste = new List();
	private SimpleServer server;
	private ParkingLot Lot[];
	private final int ParkingLotNum = 6;

	public ServerFrame(int p) throws SQLException {
		super("OCSF Server ::"+getIpV4());
		server = new SimpleServer(p, liste);
		port.setText(String.valueOf(p));

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				quit();
			}
		});

		quitB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				quit();
			}
		});

		closeB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				close();
			}
		});

		listenB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				listen();
			}
		});
        
		InetAddress addr = InetAddress.getLoopbackAddress();
		this.dbHost.setText(addr.getHostAddress());
		this.dbName.setText("vcp");
		
		
		
		Panel bottom = new Panel();
		bottom.setLayout(new GridLayout(10, 2, 5, 5));
		bottom.add(lblDBNAME);
		bottom.add(dbName);
		bottom.add(lblDBU);
		bottom.add(dbUser);
		bottom.add(lblDBP);
		bottom.add(dbPass);
		bottom.add(lblDBH);
		bottom.add(dbHost);
		bottom.add(lblDBPP);
		bottom.add(dbPort);
		bottom.add(portLB);
		bottom.add(port);
		bottom.add(backlogLB);
		bottom.add(backlog);
		bottom.add(timeoutLB);
		bottom.add(timeout);
		bottom.add(listenB);
		bottom.add(closeB);
		bottom.add(quitB);

		setLayout(new BorderLayout(5, 5));
		add("Center", liste);
		add("South", bottom);
		setSize(600, 600);
		setVisible(true);
	}

	private static String getIpV4() {
		try {
			return Inet4Address.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List getListe() {
		return liste;
	}

	public void setListe(List liste) {
		this.liste = liste;
	}

	public SimpleServer getServer() {
		return server;
	}

	public void setServer(SimpleServer server) {
		this.server = server;
	}

	

	private boolean readFields() {
		int p = Integer.parseInt(port.getText());
		int t = Integer.parseInt(timeout.getText());
		int b = Integer.parseInt(backlog.getText());

		server.setPort(p);
		server.setBacklog(b);
		server.setTimeout(t);

		// db conn setup
		String user = dbUser.getText();
		String pass = dbPass.getText();
		String host = dbHost.getText();
		String port = dbPort.getText();
		String dbname = dbName.getText();
		ConnectionManage cmgr = ConnectionManage.getInstance();
		cmgr.setUSERNAME(user);
		cmgr.setPASSWORD(pass);
		cmgr.setHost(host);
		cmgr.setPort(port);
		cmgr.setDBNAME(dbname);
		try {
			// steps to check if db exists ... otherwise install it from .sql
			ResultSet resultSet = cmgr.getInstance().getInstallerConnection().getMetaData().getCatalogs();
			//iterate each catalog in the ResultSet
			while (resultSet.next()) {
			  // Get the database name, which is at position 1
			  String databaseName = resultSet.getString(1);
			  if(databaseName.equals("vcp")){
				  liste.add("Vcp database detected :-)");
				  cmgr.close();
				  return true;
			  }
			}
			resultSet.close();
			//liste.setBackground(Color.yellow);
			liste.add("Installing vcp database...");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		
			importSQL(cmgr.getInstallerConnection(),getClass().getResourceAsStream("vcp-fixed-to-utf8.sql"));
			liste.add("Closing manager...");
			cmgr.close();
			liste.add("initializing db instance...");
			cmgr.getConnection();
			return true;
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
		
	}

	public void close() {
		liste.add("Closing server...");
		try {
			//readFields();
			server.close();
		} catch (Exception ex) {
			liste.add(ex.toString());
			liste.makeVisible(liste.getItemCount() - 1);
			liste.setBackground(Color.red);
		}
	}

	public void listen() {
		liste.add("Initializing server at "+getIpV4()+":"+server.getPort());
		try {
			if(readFields())
			   server.listen();
		} catch (Exception ex) {
			liste.add(ex.toString());
			liste.makeVisible(liste.getItemCount() - 1);
			liste.setBackground(Color.red);
		}
	}

	public void stop() {	
		server.stopListening();
	}

	public void quit() {
		System.exit(0);
	}
	
	
	public static boolean isLocalAddr(InetAddress addr) {
	    if (addr.isAnyLocalAddress() || addr.isLoopbackAddress())
	        return true;
		return false;
	}

	/**
	 * Starts the server. The default port is 12345.
	 * 
	 * @throws SQLException
	 */
	public static void main(String[] arg) throws SQLException {
		@SuppressWarnings("unused")
		ServerFrame sf;
		if (arg.length == 0)
			sf = new ServerFrame(12345);
		if (arg.length == 1)
			sf = new ServerFrame(Integer.parseInt(arg[0]));
	}
	
	public void importSQL(Connection conn, InputStream in) throws SQLException
	{
		Scanner s = new Scanner(in);
		s.useDelimiter("(;(\r)?\n)|(--\n)");
		Statement st = null;
		try
		{
			st = conn.createStatement();
			while (s.hasNext())
			{
				String line = s.next();
				if (line.startsWith("/*!") && line.endsWith("*/"))
				{
					int i = line.indexOf(' ');
					line = line.substring(i + 1, line.length() - " */".length());
					
				}

				if (line.trim().length() > 0)
				{
					st.execute(line);
				}
			}
		}
		finally
		{
			if (st != null) st.close();
		}
	}
	
}
